package fun.tan90.device.main.listener;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Pair;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import fun.tan90.device.event.EventTopic;
import fun.tan90.device.main.mapper.db1.*;
import fun.tan90.device.main.model.dataobject.db1.*;
import fun.tan90.device.main.model.enums.EnableEnum;
import fun.tan90.device.main.service.DeviceInfoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.solon.annotation.Db;
import org.noear.dami.Dami;
import org.noear.snack.ONode;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.event.AppBeanLoadEndEvent;
import org.noear.solon.core.event.EventListener;

import java.util.List;
import java.util.Objects;

@Slf4j
@Component
public class AppBeanLoadEndEvent1Listener implements EventListener<AppBeanLoadEndEvent> {

    @Db("db1")
    TransferRuleMapper transferRuleMapper;

    @Db("db1")
    SinkRuleMapper sinkRuleMapper;

    @Db("db1")
    SourceInfoMapper sourceInfoMapper;

    @Db("db1")
    SourceRuleMapper sourceRuleMapper;

    @Db("db1")
    SinkInfoMapper sinkInfoMapper;

    @Db("db1")
    ProtocolJaInfoMapper protocolJaInfoMapper;

    @Db("db1")
    ProtocolGraalInfoMapper protocolGraalInfoMapper;

    @Inject
    DeviceInfoService deviceInfoService;

    @Override
    public void onEvent(AppBeanLoadEndEvent event) {
        Dami.<String, String>bus().listen(EventTopic.DEVICE_INFO_TOPIC, listener -> {
            String deviceCode = listener.getContent();
            if (StrUtil.isBlank(deviceCode)) {
                listener.reply(null);
            } else {
                DeviceInfo deviceInfo = deviceInfoService.deviceInfo(deviceCode);
                if (Objects.nonNull(deviceInfo)) {
                    listener.reply(deviceInfo.getDeviceType());
                } else {
                    listener.reply(null);
                }
            }
        });


        Dami.<String, ONode>bus().listen(EventTopic.SOURCE_INFO_TOPIC, listener -> {
            String pluginName = listener.getContent();
            SourceInfo sourceInfo = sourceInfoMapper.selectOne(Wrappers.lambdaQuery(SourceInfo.class)
                    .select(SourceInfo::getConfig)
                    .eq(SourceInfo::getPluginName, pluginName)
                    .eq(SourceInfo::getEnable, EnableEnum.ENABLE));
            listener.reply(ONode.loadStr(sourceInfo.getConfig()));
        });

        Dami.<String, ONode>bus().listen(EventTopic.SINK_INFO_TOPIC, listener -> {
            String pluginName = listener.getContent();
            SinkInfo sinkInfo = sinkInfoMapper.selectOne(Wrappers.lambdaQuery(SinkInfo.class)
                    .select(SinkInfo::getConfig)
                    .eq(SinkInfo::getPluginName, pluginName)
                    .eq(SinkInfo::getEnable, EnableEnum.ENABLE));
            listener.reply(ONode.loadStr(sinkInfo.getConfig()));
        });


        Dami.<Pair<String, String>, ONode>bus().listen(EventTopic.PROTOCOL_JA_INFO_TOPIC, listener -> {
            List<ProtocolJaInfo> protocolJaInfos = protocolJaInfoMapper.selectList(Wrappers.lambdaQuery(ProtocolJaInfo.class)
                    .select(ProtocolJaInfo::getDeviceType, ProtocolJaInfo::getDataSource, ProtocolJaInfo::getCodeSpec, ProtocolJaInfo::getParamSpec, ProtocolJaInfo::getReturnType)
                    .eq(ProtocolJaInfo::getEnable, EnableEnum.ENABLE));
            if (CollUtil.isEmpty(protocolJaInfos)) {
                listener.reply(null);
            } else {
                listener.reply(ONode.load(protocolJaInfos));
            }
        });

        Dami.<Pair<String, String>, ONode>bus().listen(EventTopic.PROTOCOL_GRAAL_INFO_TOPIC, listener -> {
            List<ProtocolGraalInfo> protocolGraalInfos = protocolGraalInfoMapper.selectList(Wrappers.lambdaQuery(ProtocolGraalInfo.class)
                    .select(ProtocolGraalInfo::getDeviceType, ProtocolGraalInfo::getDataSource,ProtocolGraalInfo::getLanguage, ProtocolGraalInfo::getCodeSpec)
                    .eq(ProtocolGraalInfo::getEnable, EnableEnum.ENABLE));
            if (CollUtil.isEmpty(protocolGraalInfos)) {
                listener.reply(null);
            } else {
                listener.reply(ONode.load(protocolGraalInfos));
            }
        });


        Dami.<String, ONode>bus().listen(EventTopic.SOURCE_RULE_TOPIC, listener -> {
            String pluginName = listener.getContent();
            SourceRule sourceRule = sourceRuleMapper.selectOne(Wrappers.lambdaQuery(SourceRule.class)
                    .select(SourceRule::getSourceContext)
                    .eq(SourceRule::getPluginName, pluginName)
                    .eq(SourceRule::getEnable, EnableEnum.ENABLE));
            if (Objects.isNull(sourceRule)) {
                listener.reply(null);
            } else {
                listener.reply(ONode.loadStr(sourceRule.getSourceContext()));
            }
        });

        Dami.<Void, ONode>bus().listen(EventTopic.TRANSFER_RULE_TOPIC, listener -> {
            List<TransferRule> transferRules = transferRuleMapper.selectList(Wrappers.lambdaQuery(TransferRule.class)
                    .select(TransferRule::getDeviceType, TransferRule::getDataSource, TransferRule::getMap, TransferRule::getFilter)
                    .eq(TransferRule::getEnable, EnableEnum.ENABLE));
            listener.reply(ONode.load(transferRules));
        });

        Dami.<String, ONode>bus().listen(EventTopic.SINK_RULE_TOPIC, listener -> {
            String pluginName = listener.getContent();
            List<SinkRule> sinkRules = sinkRuleMapper.selectList(Wrappers.lambdaQuery(SinkRule.class)
                    .select(SinkRule::getDeviceType, SinkRule::getDataSource, SinkRule::getSinkContext)
                    .eq(SinkRule::getPluginName, pluginName)
                    .eq(SinkRule::getEnable, EnableEnum.ENABLE));
            listener.reply(ONode.load(sinkRules));
        });
    }
}